home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PAS_0493 / SCROLL.PAS < prev    next >
Pascal/Delphi Source File  |  1993-04-22  |  6KB  |  167 lines

  1. {─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
  2. Msg  : 293 of 310
  3. From : Kai Rohrbacher                      2:241/7451.7         15 Apr 93  23:14
  4. To   : David Todd                          1:259/423.0
  5. Subj : Mode X/Y
  6. ────────────────────────────────────────────────────────────────────────────────
  7. KR>> Basically,  Mode  Y  works  like  this:  use  the BIOS to switch
  8. KR>> into normal 320x200x256  mode,  then reprogram the sequencer to
  9. KR>> unchain the 4 bitplanes. This  results  in  a bitplaned VRAM layout
  10. KR>> very similiar to the EGA/VGA's 16 color modes:
  11. DT>
  12. DT> By saying 4 bitplanes, are you referering to the pages? I know that
  13. DT> you can specify 4 pages in mode X/Y.
  14. No, it just means that with each VRAM address, 4 physically different RAM cells
  15. can be addressed: you may think of a "3-dimensional" architecture of your VGA's
  16. VRAM (ASCII sucks, I know...)
  17.              ____________
  18.             |*  plane3   |
  19.          ___|_________   |
  20.         |*   plane2   |__|
  21.      ___|__________   |
  22.     |*   plane1    |__|
  23.  ___|___________   |
  24. |*   plane0     |__|
  25. |               |
  26. |_______________|
  27.  
  28. The upper left corner of each bitplane (marked by a "*") is referenced with the
  29. address $A000:0, but refers to 4 pixels! It is quite simple: instead of
  30. counting "$A000:0 is the first pixel, $A000:1 is the 2nd, $A000:2 is the 3rd,
  31. $A000:3 is the 4th, $A000:4 is the 5th" (as you would do in the normal BIOS
  32. mode 320x200x256), the pixels now are distributed this way: "$A000:0/plane 0 is
  33. the 1st, $A000:0/plane 1 is the 2nd, $A000:0/plane 2 is the 3rd, $A000:0/plane
  34. 3 is the 4th, $A000:1/plane 0 is the 5th" and so on.
  35. So obviously, w/o doing some "bitplane switching", you are always restricted to
  36. work on one bitplane at a time --the one actually being activated. If this is
  37. plane0, you may only change pixels which (x mod 4) remainder is 0, the other
  38. ones with (x mod 4)=1|2|3 aren't accessible, you have to "switch to the plane"
  39. first. Thus the name "bitplane"!
  40.  
  41. DT> And what exactly does "unchain" mean, as opposed to "chained". I have the
  42. DT> feeling that they refer to each page(bitplane) being on its own.
  43. Huhh, that would go pretty much into details; a bit simplified, "chained" means
  44. that the bitplanes mentioned above are "glued" together for the simple BIOS
  45. mode, so that bitplane switching isn't necessary anymore (that is equivalent in
  46. saying that one VRAM address refers to one RAM cell). As there are only 65536
  47. addresses in the $A000 segment and we need 320x200=64000 for a full page, you
  48. only have 65536/64000=1.024 pages therefore. "Unchaining" means to make each
  49. bitplane accessible explicitely.
  50.  
  51. DT> Now here is another problem I don't understand. I am familiar with VGA's
  52. DT> mode 13h which has one byte specifying each pixel on the screen,
  53. DT> therefore 1 byte = 1 pixel. But this takes up 64k.
  54. Small note on this: not 64K, but only 64000 bytes!
  55.  
  56. DT> But how do you have one address represent 4 pixels, which only occupies
  57. DT> 16000 address bytes, and still be able to specify 256 colours. Won't 4
  58. DT> bitplanes at 320x200 each take up 64000x4 bytes of space?
  59. We have 320x200=64000 pixels=64000 bytes. As each 4 pixels share one address,
  60. 16000 address bytes per page suffice. The $A000 segment has 64K address bytes,
  61. thus 4*64K=256K VRAM can be addressed. 64K address bytes = 65536 address bytes;
  62. 65536/16000 = 4.096 pages.
  63.  
  64. DT> How would you go about adjusting the vertical retraces, and memory
  65. DT> location you mentioned.
  66. Assuming that the DX-register has been set to 3DAh or 3BAh for color/monochrome
  67. display, respectively, you can trace the status of the electronic beam like
  68. this:
  69.     @WaitNotVSyncLoop:
  70.       in   al,dx
  71.       and  al,8
  72.       jnz  @WaitNotVSyncLoop
  73.     @WaitVSyncLoop:
  74.       in   al,dx
  75.       and  al,8
  76.       jz   @WaitVSyncLoop
  77.     now change the starting address
  78.  
  79. (If you use "1" instead of "8" and exchange "jz" <-> "jnz" and vice vs., then
  80. you sync on the shorter horizontal retrace (better: horizontal _enable_)
  81. signal).
  82. The alteration of the starting address is done by the code I already posted in
  83. my first mail! (Its done by addressing the registers $C and $D of the
  84. CRT-controller).
  85. Note that reprogramming the starting address isn't restricted to mode X/Y, you
  86. can have it in normal mode 13h, too: there are 65536 addresses available, but
  87. only 64000 needed, thus giving a scroll range of 4.8 lines! And to complicate
  88. things even further, for start addressing purposes, even the BIOS mode is
  89. planed (that is, a row consists of 320/4 bytes only). Just for the case you
  90. don't believe...}
  91.  
  92. PROGRAM Scroll;
  93. VAR CRTAddress,StatusReg:WORD;
  94.     a:ARRAY[0..199,0..319] OF BYTE ABSOLUTE $A000:0000;
  95.     i,j:WORD;
  96.  
  97. PROCEDURE SetAddress(ad:WORD); ASSEMBLER;
  98. ASM
  99.   MOV BX,ad
  100.  
  101.   MOV DX,StatusReg
  102.   @WaitNotVSyncLoop:
  103.     in   al,dx
  104.     and  al,8
  105.     jnz  @WaitNotVSyncLoop
  106.   @WaitVSyncLoop:
  107.     in   al,dx
  108.     and  al,8
  109.     jz   @WaitVSyncLoop
  110.  
  111.   MOV DX,CRTAddress
  112.   MOV AL,$0D
  113.   CLI
  114.   OUT DX,AL
  115.   INC DX
  116.   MOV AL,BL
  117.   OUT DX,AL
  118.   DEC DX
  119.   MOV AL,$0C
  120.   OUT DX,AL
  121.   INC DX
  122.   MOV AL,BH
  123.   OUT DX,AL
  124.   STI
  125. END;
  126.  
  127. BEGIN
  128.  IF ODD(port[$3CC])
  129.   THEN CRTAddress:=$3D4
  130.   ELSE CRTAddress:=$3B4;
  131.  StatusReg:=CRTAddress+6;
  132.  ASM
  133.   MOV AX,13h
  134.   INT 10h
  135.  END;
  136.  
  137.  FOR i:=1 TO 1000 DO
  138.   a[Random(200),Random(320)]:=Random(256);
  139.  
  140.  {scroll horizontally by 4 pixels}
  141.  FOR i:=1 TO 383 DO SetAddress(i);
  142.  FOR i:=382 DOWNTO 0 DO SetAddress(i);
  143.  
  144.  {scroll vertically by 1 row}
  145.  FOR j:=1 TO 20 DO
  146.   BEGIN
  147.    FOR i:=1 TO 4 DO SetAddress(i*80);
  148.    FOR i:=3 DOWNTO 0 DO SetAddress(i*80)
  149.   END;
  150.  
  151.  ASM {back to 80x25}
  152.   MOV AX,3
  153.   INT 10h
  154.  END;
  155.  
  156. END.
  157.  
  158. DT> Your said you could specify how the memory can be layed out by the user,
  159. DT> but I am in need of what each PORT does. I know you have to send
  160. DT> different values to the port to program it, but I have no idea what each
  161. DT> port reads.
  162. There are incredibly much registers to program! For a good overview of most of 
  163. them, try to get your hands on a copy of VGADOC*.* by Finn Thoegersen
  164. (jesperf@daimi.aau.dk) which covers programming a lot of SVGA's chipsets, too.
  165.  
  166. cu,
  167.    Kai